package com.xiaotu.spider.pptv.pageprocessor;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.model.TVPubCommentModel;
import com.xiaotu.common.model.TVRecordModel;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.KeywordEncode;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.TVProcessUtils;
import com.xiaotu.spider.APageProcessor;

/**
 * @类名 PPTVPageProcessor
 * @日期 2017年2月14日
 * @作者 高海军
 * @功能 爬取PPTV电视剧记录信息[tab_tv_record]
 */
@Component("PPTVPageProcessor")
@Scope("prototype")
public class PPTVPageProcessor extends APageProcessor
{
    private static final String SEARCH_URL = "http://search.pptv.com/s_video?kw=";

    @Override
    protected Request getStartRequest(JSONObject target)
    {
        return new Request(
                SEARCH_URL + KeywordEncode.encode(target.getString("tvName")));
    }

    @Override
    public void process(Page page)
    {
        Map<String, Object> tvInfoMap = page.getRequest().getExtras();
        if (Constants.PageDataType.TV_RECORD.equals(this.getPageDataType(page)))
            this.searchListProcess(page, tvInfoMap);
        else
            this.commentProcess(page, tvInfoMap);
    }

    public void searchListProcess(Page page, Map<String, Object> tvInfoMap)
    {
        // 评分
        List<String> scores = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                        "fr']/dl/dt/span/text()")
                .all();
        List<String> titles = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                        "fr']/dl/dt/a/@title")
                .all();
        List<String> playCounts = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd fr']/dl")
                .all();
        List<String> commentIds = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                        "fr']/dl/dt/a/@external_url")
                .all();
        // 作品div列表，用于获取年份
        List<String> divList = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']")
                .all();
        String firstTimes = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                        "fr']/dl/dd/ul/li[4]/text()").toString();
        if(firstTimes.contains("年代")){
        	String firstTime =page.getHtml()
                    .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                            "fr']/dl/dd/ul/li[4]/span/a/text()").toString();
        	tvInfoMap.put("firstTime", firstTime);
        }
        String firstTimess = page.getHtml()
                .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                        "fr']/dl/dd/ul/li[5]/text()").toString();
        if(firstTimess.contains("年代")){
        	String firstTime =page.getHtml()
                    .xpath("//div[@id='search-result']/div[@class='scon cf']/div[@class='bd " +
                            "fr']/dl/dd/ul/li[5]/span/a/text()").toString();
        	tvInfoMap.put("firstTime", firstTime);
        }
        // List<String> mapTvtypes = page.getHtml()
        // .xpath("//div[@id='search-result']/div[@class='scon cf']")
        // .all();

        if (titles.size() != scores.size() || titles.size() != playCounts.size()
                || titles.size() != commentIds.size()
                // || titles.size() != mapTvtypes.size()
                || titles.size() != divList.size())
            throw new SpiderException(
                    SpiderExceptionCode.DataInvalideException);

        List<TVRecordModel> tvList = new ArrayList<>();
        for (int i = 0; i < titles.size(); i++)
        {
            String title = titles.get(i);
            Html html = new Html(divList.get(i));
            // Html mapTvtypeHtml = new Html(mapTvtypes.get(i));
            String mapTvtype = StringUtils.isEmpty(
                    html.xpath("//div[@class='bd fr']/div[@class='tabview']")
                            .toString()) ? "2" : "1";

            // String year = html
            // .xpath("//div[@class='bd
            // fr']/dl[@class='tit']/dd[@class='pinfo']/ul[@class='cf']/li[4]//a/text()")
            // .get();

            List<String> actorsAndDirectors = html
                    .xpath("//ul/li/span/a/text()").all();
            actorsAndDirectors.remove("");
            for (int j = actorsAndDirectors.size() - 1; j >= 0; j--)
            {
                if (StringUtils.isEmpty(actorsAndDirectors.get(j)))
                {
                    actorsAndDirectors.remove(j);
                }
                else
                {
                    actorsAndDirectors.set(j, actorsAndDirectors.get(j).trim());
                }
            }

            if (TVProcessUtils.tvMatched(tvInfoMap, title, mapTvtype,
                    actorsAndDirectors, actorsAndDirectors))
            {
                Pattern p = Pattern.compile("播放.{0,}<span>(.*)</span>");
                Matcher m = p.matcher(playCounts.get(i));
                String playCount = null;
                if (m.find())
                    playCount = m.group(1).replace(",", "");

                String score = scores.get(i);
                if (StringUtils.isNotEmpty(score))
                    score = score.substring(0, score.indexOf("分") > 0
                            ? score.indexOf("分") : score.length());

                this.addCommentLink(page, commentIds.get(i));

                if (StringUtils.isEmpty(playCount) && StringUtils.isEmpty(score))
                    continue;

                tvList.add(new TVRecordModel(tvInfoMap.get("tvid") + "",
                        title + "",
                        Constants.SiteName.PPTV, score, playCount, null,
                        null, null, null,null,tvInfoMap.get("firstTime") + ""));
            }

        }

        if (tvList.isEmpty())
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        page.putField(TVRecordModel.class.getName() + "List", tvList);

    }

    private void addCommentLink(Page page, String commentIdStr)
    {
        // 获取评论
        Matcher m = Pattern.compile("chn=(\\d{1,})&").matcher(commentIdStr);
        if (m.find())
        {
            PageUtils.addTargetRequest(page,
                    "http://apicdn.sc.pptv.com/sc/v3/pplive/ref/vod_"
                            + m.group(1)
                            + "/feed/list?appplt=web&action=1&pn=0&ps=20&from=web&version=1.0.0" +
                            "&format=jsonp&cb=pplive_callback_1",
                    page.getRequest().getExtras());
        }
    }

    private void commentProcess(Page page, Map<String, Object> tvInfoMap)
    {
        String comments = page.getRawText();
        comments = comments.substring(comments.indexOf("{"),
                comments.lastIndexOf("}") + 1);
        JSONObject commentsJson = JSONObject.fromObject(comments);

        // 剧公众评论
        JSONArray commentList = commentsJson.getJSONObject("data")
                .getJSONArray("page_list");

        List<TVPubCommentModel> list = new ArrayList<TVPubCommentModel>();

        Date data;
        for (int j = 0; j < commentList.size(); j++)
        {
            JSONObject comment = commentList.getJSONObject(j);
            String createtime = comment.getString("create_time");
            // 咨询时间早于2015.10月份，不加入
            Date base = DateUtils.getDate("2015-10-01 00:00:00",
                    "yyyy-MM-dd HH:mm:ss");

            if (StringUtils.isEmpty(createtime))
                continue;
            data = new Date(Long.valueOf(createtime));
            if (data.getTime() < base.getTime())
                continue;

            list.add(new TVPubCommentModel(tvInfoMap.get("tvid") + "",
                    tvInfoMap.get("tvName") + "", Constants.SiteName.PPTV,
                    comment.getJSONObject("user").getString("nick_name"),
                    comment.getString("content"), createtime, null, null));
        }
        if (list.isEmpty())
            throw new SpiderException(
                    SpiderExceptionCode.DataInvalideException);

        page.putField(TVPubCommentModel.class.getName(), list);
    }

    @Override
    protected String getSpiderType()
    {
        return Constants.SpiderTaskType.TV_PPTV;
    }

    @Override
    public String getPageDataType(Page page)
    {
        if (page.getUrl().toString().contains(SEARCH_URL))
            return Constants.PageDataType.TV_RECORD;
        return Constants.PageDataType.TV_COMMENT;
    }

}
